/**
 * @class 行星磁场范围实体
 * @author DuskyHuang 圣子
*/

import { _decorator, Component, MeshRenderer, Color, Vec4 } from 'cc';
import { planetary } from 'proxies';
const { ccclass, property } = _decorator;

@ccclass('cocosmos.magnetics')
export class Magnetics extends Component {

    @property(MeshRenderer) public spindle: MeshRenderer = null;
    @property(MeshRenderer) public closeInner: MeshRenderer = null;
    @property(MeshRenderer) public closeMiddle: MeshRenderer = null;
    @property(MeshRenderer) public closeOuter: MeshRenderer = null;
    @property(MeshRenderer) public openInner: MeshRenderer = null;
    @property(MeshRenderer) public openOuter: MeshRenderer = null;

    protected onEnable(): void { this._syncToCenter(); }
    protected update(): void { this._syncToCenter(); }

    public reloadConfig(config: planetConfig): void {
        this.node.children.forEach(child => child.active = false);
        if (!config || !config.magnetics) return;
        const { spindle, closes, opens } = config.magnetics;
        this._reloadOneMaterial(this.spindle, spindle);
        if (closes) {
            const { inner, middle, outer } = closes;
            this._reloadOneMaterial(this.closeInner, inner);
            this._reloadOneMaterial(this.closeMiddle, middle);
            this._reloadOneMaterial(this.closeOuter, outer);
        }
        if (opens) {
            const { inner, outer } = opens;
            this._reloadOneMaterial(this.openInner, inner);
            this._reloadOneMaterial(this.openOuter, outer);
        }
    }

    private _reloadOneMaterial(mesh: MeshRenderer, config: magnetic): void {
        if (!config) return;
        mesh.node.active = true;
        const [scale, mainColor, lineColor, lineStrength, lineDensity, lineSpeed, noiseStrength] = config;
        const s = scale ?? 1;
        mesh.node.setScale(s, s, s);
        const mat = mesh.material;
        mat.setProperty('mainColor', this._setColor(mainColor));
        mat.setProperty('lineColor', this._setColor(lineColor));
        mat.setProperty('args', v4a.set(lineStrength ?? 0.5, lineDensity ?? 24, lineSpeed ?? 0, noiseStrength ?? 0));
    }

    private _syncToCenter(): void {
        const { center, unbelt } = planetary;
        this.node.setWorldScale(center.node.worldScale);
        this.node.setWorldPosition(center.node.worldPosition);
        if (unbelt) {
            center.faceToSun(this.node);
        }
    }

    private _setColor(arr: vec4<bit8>): Color {
        color.set(arr[0] ?? 0, arr[1] ?? 0, arr[2] ?? 0, arr[3] ?? 0);
        return color;
    }
}

const color = new Color;
const v4a = new Vec4;